<?php
/**
 * Creates an html link depending on Zend_Acl.
 * Automatically adds attributes and parameters.
 *
 * @author Sergeev Anton xapon91@gmail.com
 * @package View_Helper_Href
 * @copyright Copyright (c) 2010 Sergeev Anton
 * @license http://www.gnu.org/licenses/gpl.html GNU GPL v3 license
 */


/*
FROM: http://www.zfsnippets.com/snippets/view/id/75
USAGE:
	echo $this->href(array('action'=>'list-application-photos', 'params'=>array('id'=>3), 'checkAcl'=>true, 'label'=>'list-application-photos'));

*/
class My_View_Helper_Href extends Zend_View_Helper_Url {
	/**
	 * @var array
	 * Default options
	 */
	private $options=array(
							'module'		=>null,       	//default module
							'controller'	=>null,       	//default controller
							'action'		=>null,        	//default action
							'params'		=>array(),      //array of parameters
							'router'		=>'default',    //default router
						   	'reset'			=>false,	 	//reset router defaults

						   	'url'			=>null,		 	//Url like "http://google.com", will be used if controller is null
							'label'			=>null,		    //Link label, text or what you want between <a> and </a>
							'translate'		=>false,		    //translate Link label?
							'attribs'		=>array(),      //Link attributes, e.g. class or id
						   	//'resource'	=>null,         //ACL resource name, if not set - controller name will be used
						   	//'resource-prefix'=>'mvc:',	//If "resource" option is null, the ACL will be checked with this option connected with "controller" option
						   	//'privilege'	=>null,    	 	//ACL privilege name, if null - action name will be used
						   	'checkAcl'		=>true,         //check if this link allowed by Zend_Acl
						   	'aclObj'		=>'Zend_Acl',	//Zend_Acl instance. If option is string, will try to get Zend_Acl from Zend_Registry by this string
						   	'linkrole'		=>'',   		//String - link's role name. required privilege/role - if empty, will query db for url params and get the role name from db.
						   	'userrole'		=>'',   		//String - user's role name.  user has this role. if empty will get this->view->authdata->role
						   	'printLabelIfNoPerm' => true,	//if the user does not allowed for link, shall we print only the label instead of the link or not.
						  );
	 /**
	  * @param array $options
	  * @return string or bool FALSE if options are incorrect or access denied
	 */
    public function href (array $options)
    {

    	$options = array_merge($this->options, $options);
    	$url = $this->setUrl($options);

    	$attribsArr = array();
    	if ( !empty($options['attribs']) ) {
	    	foreach ($options['attribs'] as $attrib=>$value)
	    		$attribsArr[] = $attrib. '="'.$value.'"';
	    }

		if ($options['translate']) {
			//$translateObj = Zend_Registry::get('Zend_Translate');
			//$options['label'] = $translateObj->translate($options['label']);
			$options['label'] = $this->view->translate($options['label']);
		}
	    $link = '<a href="'.$url.'"'. (!empty($attribsArr) ? ' '. (implode(' ', $attribsArr)) : '' ) .'>'.$options['label'].'</a>';

    	if ($options['checkAcl'] == true) {
    		if ($this->checkAcl($options)) {
    			return $link;
    		}

			//return false;
			if ($options['printLabelIfNoPerm']) {
				return $options['label'];
			}
			return false;
    	} else {
    		return $link;
    	}
    }

    /**
      * Construct URL based on standart url helper
      * @param array $options
      * @return string
      */
    private function setUrl($options) {

    	//if (!empty($options['module']) || !empty($options['controller']) || !empty($options['action']) ) {

    		$options['core'] = array();
    		if (!empty($options['module'])) {
    			$options['core']['module'] = $options['module'];
    		}
    		if (!empty($options['controller'])) {
    			$options['core']['controller'] = $options['controller'];
    		}
    		if (!empty($options['action'])) {
    			$options['core']['action'] = $options['action'];
    		}
    		//print_r($options['core']);exit;

    		$url = $this->url(
    			array_merge($options['core'], $options['params']),
    			$options['router'],
    			$options['reset']);

//    	} else if (!empty($options['url'])) {
//    		$url = $options['url'];
//    	} else {
//    		$url = 'javascript:void(0);';
//    	}
    	return $url;
    }

    /**
      * Check if current options are allowed by Zend_Acl
      * @param array $options
      * @return bool
      */
    private function checkAcl($options) {


			$aclObj 	= Zend_Registry::get($options['aclObj']);

	    	$module 	= (!empty($options['module']) 		? $options['module'] 		: Zend_Registry::get('currentModuleName'));
	    	$controller = (!empty($options['controller']) 	? $options['controller'] 	: Zend_Registry::get('currentControllerName'));
	    	$action 	= (!empty($options['action']) 		? $options['action'] 		: Zend_Registry::get('currentActionName'));

	    	$resource 	= $module.':'.$controller;

	    	$userrole 	= (!empty($options['userrole']) ? $options['userrole'] : $this->view->authdata->role);
	    	$linkrole 	= $options['linkrole'];

	    	if (!$linkrole) {
	    		$model = new Default_Model_DbTable_Navigation();
	    		$row = $model->findNavigation($module, $controller, $action);

	        	if (empty($row)) {
	        		$defaultRole = 'developer';
                    $moduleDefaultRole = $model->getModuleDefaultRole($module);

                    $data['module_name'] = $module;
	        		$data['controller_name'] = $controller;
	        		$data['action_name'] = $action;
                    $data['role_name'] = (($moduleDefaultRole) ? $moduleDefaultRole : $defaultRole);
                    $data['name'] = $module.'_'.$controller.'_'.$action;
                    $data['is_external'] = '0';
	        		$newNavigation = $model->addNavigation($data);

	        		$row->role_name = $defaultRole;
	        	}

		    	if (!$row->role_name) {
		    		return false;
		    	}
		    	$linkrole = $row->role_name;
	    	}
	    	if (!$aclObj->hasRole($linkrole)) {
	    		return false;
	    	}
	    	if (!$aclObj->hasRole($userrole)) {
	    		return false;
	    	}
			if (!$aclObj->has($resource)) {
				$aclObj->addResource($resource);
			}

	    	$aclObj->allow($linkrole, $resource, $action);
	    	if ($aclObj->isAllowed($userrole, $resource, $action)) {
	    		return true;
	    	}
    		return false;
    }
}